﻿/*****************************************************************************
 
 Use of Ext is under the Ext JS license, for more information, 
 please visit http://extjs.com/products/license.php page. 
  
 You should confirm that you have read, understood and accept ethical criteria listed. 
 If not, see <http://www.mvcnext.com/license/>.
  
 Version: 1.0.0.0
 Website: http://www.mvcnext.com/
 
 Copyright (c) Yoganand R. All rights reserved.
 For continued development and updates, visit http://yogsbreath.net
 
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Web.UI;
using System.Text;

namespace MVCnExt.Web.UI.Ext
{
    /// <summary>
    /// This class represents the primary interface of a component based grid control.
    /// </summary>
    [ToolboxData("<{0}:ExtGridPanel runat=\"server\"></{0}:ExtGridPanel>")]
    [Description("This class represents the primary interface of a component based grid control.")]
    public class ExtGridPanel : ExtBoxComponent
    {
        private List<ExtGridView> _view = new List<ExtGridView>();

        public override List<ScriptReference> GetScriptReferences()
        {
            return base.GetScriptReferences();
        }

        public override IList<ScriptDescriptor> GetScriptDescriptors()
        {
            IList<ScriptDescriptor> list = base.GetScriptDescriptors();

            ScriptControlDescriptorBase desc = (ScriptControlDescriptorBase)list[0];

            desc.Type = "Ext.grid.GridPanel";

            String[] properties = new String[]{
                "autoExpandColumn", "autoExpandMax", "autoExpandMin", "deferRowRender", "disableSelection",
                "enableColumnHide", "enableColumnMove", "enableColumnResize", "enableDragDrop", "enableHdMenu",
                "hideHeaders", "minColumnWidth", "monitorWindowResize", "stripeRows", "trackMouseOver",
                "autoEncode", "clicksToEdit", "fireSelectOnLoad", "loadMask", "autoFill", "height", "width"
            };

            Type component = typeof(ExtGridPanel);

            foreach (String property in properties)
            {
                PropertyInfo i = component.GetProperty(property);

                if (i == null)
                    throw new InvalidOperationException(String.Format("Property not found, 'ExtGridPanel.{0}'", property));

                Object value = i.GetValue(this, null);

                if (value == null)
                {
                    continue;
                }

                if (!(value is String))
                    desc.AddPropertyBase(property, value);
                else
                    desc.AddPropertyBase(property, String.Format("'{0}'", value));
            }

            //add items
            if (view.Count != 0)
            {
                // build items list
                StringBuilder itemList = new StringBuilder();

                for (int i = 0; i < view.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        itemList.Append(",");
#if DEBUG
                        itemList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = view[i].GetScriptDescriptors();

                    // write the item's config to the list
                    itemList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                desc.AddPropertyBase("view", itemList);
            }


            //add column model
            if (cm != null && cm.Count != 0)
            {
                // build items list
                StringBuilder tabList = new StringBuilder("new Ext.grid.ColumnModel([");

                for (int i = 0; i < cm.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        tabList.Append(",");
#if DEBUG
                        tabList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = cm[i].GetScriptDescriptors();

                    // write the item's config to the list
                    tabList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.ConfigOnly));
                }

                tabList.Append("])");

                desc.AddPropertyBase("cm", tabList);
            }

            //add selection model
            if (selModel != null && selModel.Count != 0)
            {
                // build items list
                StringBuilder tabList = new StringBuilder();

                for (int i = 0; i < selModel.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        tabList.Append(",");
#if DEBUG
                        tabList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = selModel[i].GetScriptDescriptors();

                    // write the item's config to the list
                    tabList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                desc.AddPropertyBase("selModel", tabList);
            }

            //add items
            if (store.Count != 0)
            {
                // build items list
                StringBuilder itemList = new StringBuilder();

                for (int i = 0; i < store.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        itemList.Append(",");
#if DEBUG
                        itemList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = store[i].GetScriptDescriptors();                    

                    // write the item's config to the list
                    itemList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                desc.AddPropertyBase("store", itemList);
            }

            return list;
        }

        #region Public Properties

        /// <summary>
        /// The content to be added to the Container
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(ExtContainer))]
        [TemplateInstance(TemplateInstance.Single)]
        public List<ExtColumn> cm { get; set; }

        /// <summary>
        /// The content to be added to the Container
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(ExtContainer))]
        [TemplateInstance(TemplateInstance.Single)]
        public List<ExtRowSelectionModel> selModel { get; set; }


        /// <summary>
        /// The id of a column in this grid that should expand to fill unused space. This id can not be 0.
        /// </summary>        
        [Description("The id of a column in this grid that should expand to fill unused space. This id can not be 0.")]
        public String autoExpandColumn { get; set; }

        public Boolean? loadMask { get; set; }


        /// <summary>
        /// True to auto expand the columns to fit the grid when the grid is created
        /// </summary>
        public Boolean? autoFill { get; set; }

        /// <summary>
        /// The maximum width the autoExpandColumn can have (if enabled). Defaults to 1000.
        /// </summary>
        [DefaultValue(1000)]
        [Description("The maximum width the autoExpandColumn can have (if enabled). Defaults to 1000.")]
        public Unit? autoExpandMax { get; set; }

        /// <summary>
        /// The minimum width the autoExpandColumn can have (if enabled). defaults to 50.
        /// </summary>
        [DefaultValue(50)]
        [Description("The minimum width the autoExpandColumn can have (if enabled). defaults to 50.")]
        public Unit? autoExpandMin { get; set; }

        /// <summary>
        /// The Ext.grid.ColumnModel to use when rendering the grid (required).
        /// </summary>
        [Description("The Ext.grid.ColumnModel to use when rendering the grid (required).")]
        public Boolean? deferredRender { get; set; }

        /// <summary>
        /// True to enable deferred row rendering. Default is true.
        /// </summary>
        [DefaultValue(true)]
        [Description("True to enable deferred row rendering. Default is true.")]
        public Boolean? deferRowRender { get; set; }

        /// <summary>
        /// True to disable selections in the grid (defaults to false). - ignored a SelectionModel is specified.
        /// </summary>
        [Description("True to disable selections in the grid (defaults to false). - ignored a SelectionModel is specified.")]
        public Boolean? disableSelection { get; set; }

        /// <summary>
        /// True to enable hiding of columns with the header context menu.
        /// </summary>
        [DefaultValue(true)]
        [Description("True to enable hiding of columns with the header context menu.")]
        public Boolean? enableColumnHide { get; set; }

        /// <summary>
        /// True to enable drag and drop reorder of columns.
        /// </summary>
        [DefaultValue(true)]
        [Description("True to enable drag and drop reorder of columns.")]
        public Boolean? enableColumnMove { get; set; }

        /// <summary>
        /// False to turn off column resizing for the whole grid (defaults to true).
        /// </summary>
        [DefaultValue(true)]
        [Description("False to turn off column resizing for the whole grid (defaults to true).")]
        public Boolean? enableColumnResize { get; set; }

        /// <summary>
        /// True to enable drag and drop of rows.
        /// </summary>        
        [Description("True to enable drag and drop of rows.")]
        public Boolean? enableDragDrop { get; set; }

        /// <summary>
        /// True to enable the drop down button for menu in the headers.
        /// </summary>
        [DefaultValue(true)]
        [Description("True to enable the drop down button for menu in the headers.")]
        public Boolean? enableHdMenu { get; set; }

        /// <summary>
        /// True to hide the grid's header (defaults to false).
        /// </summary>        
        [Description("True to hide the grid's header (defaults to false).")]
        public Boolean? hideHeaders { get; set; }

        /// <summary>
        /// The minimum width a column can be resized to. Defaults to 25.
        /// </summary>
        [DefaultValue(25)]
        [Description("The minimum width a column can be resized to. Defaults to 25.")]
        public Unit? minColumnWidth { get; set; }

        /// <summary>
        /// True to autoSize the grid when the window resizes. Defaults to true.
        /// </summary>
        [DefaultValue(true)]
        [Description("True to autoSize the grid when the window resizes. Defaults to true.")]
        public Boolean? monitorWindowResize { get; set; }

        private List<Store> _store = new List<Store>();

        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public virtual List<Store> store
        {
            get
            {
                return _store;
            }
        }

        ///// <summary>
        ///// The data store to use.
        ///// </summary>
        //[Description("The data store to use.")]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        //[PersistenceMode(PersistenceMode.InnerProperty)]
        //[TemplateContainer(typeof(ExtContainer))]
        //[TemplateInstance(TemplateInstance.Single)]
        //public ExtStore store { get; set; }

        /// <summary>
        /// The data store to use.
        /// </summary>
        [Description("The data store to use.")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(ExtContainer))]
        [TemplateInstance(TemplateInstance.Single)]
        public ExtSimpleStore simpleStore { get; set; }

        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public virtual List<ExtGridView> view
        {
            get
            {
                return _view;
            }
        }

        /// <summary>
        /// True to stripe the rows. Default is false.
        /// </summary>        
        [Description("True to stripe the rows. Default is false.")]
        public Boolean? stripeRows { get; set; }

        /// <summary>
        /// True to highlight rows when the mouse is over. Default is true.
        /// </summary>
        [DefaultValue(true)]
        [Description("True to highlight rows when the mouse is over. Default is true.")]
        public Boolean? trackMouseOver { get; set; }

        /// <summary>
        /// True to automatically HTML encode and decode values pre and post edit (defaults to false).
        /// </summary>        
        [Description("True to automatically HTML encode and decode values pre and post edit (defaults to false).")]
        public Boolean? autoEncode { get; set; }

        /// <summary>
        /// The number of clicks on a cell required to display the cell's editor (defaults to 2).
        /// </summary>   
        [DefaultValue(2)]
        [Description("The number of clicks on a cell required to display the cell's editor (defaults to 2).")]
        public Int16? clicksToEdit { get; set; }

        [Description("Set init selecetion without event fires")]
        public Boolean? fireSelectOnLoad { get; set; }

        public override Unit? height { get; set; }

        public override Unit? width { get; set; }

        #endregion
    }
}
